/**
 * Title: MyPriorityQueueBase2Test.java
 * Description: Tests the grow(int) method from MyPriorityQueue class using equivalence partitioning analysis 
 * 				for basis step 2 (One element queue)
 * Copyright: Copyright (c) 2011
 * Company: University of Texas at Arlington
 * @author: Duy Nguyen and Shreya Mamadapur
 * @version 1.0
 */

import java.util.Random;

import junit.framework.TestCase;
import junitx.util.PrivateAccessor;

import org.junit.Before;
import org.junit.Test;

public class MyPriorityQueueBase2Test extends TestCase {
	private static MyPriorityQueue mpq;

	static IntegerElement e;
	static Object[] o, o1;
	static int exceptionThrown;
	int queueLength, capacity;
	private Random random;
	int defaultCapacity = 0;

	@Before
	public void setUp() throws Exception {
		e = new IntegerElement(0);
		random = new Random();

		// obtain the default capacity by accessing the private variable called DEFAULT_INITIAL_CAPACITY
		defaultCapacity = Integer.parseInt(PrivateAccessor.getField(
				MyPriorityQueue.class, "DEFAULT_INITIAL_CAPACITY").toString());
	}

	/**
	 * Test 1 - On a one element queue, 
	 * 			test the grow method by passing in a negative desired capacity, an exception should be thrown
	 * 
	 */
	@Test
	public void testGrowWithNegativeMinCapacity() {
		boolean exceptionThrown = false;

		mpq = new MyPriorityQueue();

		// add an element to the queue
		e.setValue(random.nextInt(100));
		mpq.add(e);
		
		//convert the queue to an array and obtain its length
		o1 = mpq.toArray();
		queueLength = o1.length;

		assertEquals(1, queueLength);

		try {
			// access private method
			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { new Integer(-10) });
		} catch (java.lang.OutOfMemoryError e) {
			exceptionThrown = true;
		} catch (Throwable e) {
		}

		assertTrue(exceptionThrown);
	}

	/**
	 * Test 2 - On a one element queue, 
	 * 			test the grow method by passing in a 0 desired capacity,
	 * 			the new capacity should still be the default value
	 * 
	 */
	@Test
	public void testGrowWithZeroMinCapacityAndDefaultInitCap() {

		mpq = new MyPriorityQueue();

		e.setValue(random.nextInt(100));
		
		//add an element to the queue
		mpq.add(e);

		o1 = mpq.toArray();

		queueLength = o1.length;

		assertEquals(1, queueLength);

		try {

			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { new Integer(0) });
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			
			capacity = o.length;
			assertEquals(defaultCapacity, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

		
	}

	/**
	 * Test 3 - On an empty queue, 
	 * 			test the grow method by passing in a positive desired capacity,
	 * 			the new capacity should still be the default value (since 10 here is less than the default cap)
	 * 
	 */
	@Test
	public void testGrowWithPositiveMinCapacityAndDefaultInitCap() {

		mpq = new MyPriorityQueue();

		e.setValue(random.nextInt(100));
		mpq.add(e);

		o1 = mpq.toArray();

		queueLength = o1.length;

		assertEquals(1, queueLength);

		try {
			// access private method
			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { 10 });
			
			// access private variable
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");			
			capacity = o.length;
			assertEquals(defaultCapacity, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}
		
	}

	/**
	 * Test 4 - On a one element queue, 
	 * 			test the grow method testing to see if the new capacity 
	 * 			is the same as the initial capacity
	 * 
	 */
	@Test
	public void testGrowWithPositiveMinCapacityAndInitCapGreaterThan64() {
		// initial capacity
		int inputCap = 64 + random.nextInt(100);
		mpq = new MyPriorityQueue(inputCap);

		e.setValue(random.nextInt(100));
		
		//add an element to the queue
		mpq.add(e);

		o1 = mpq.toArray();

		queueLength = o1.length;

		assertEquals(1, queueLength);

		try {
			o = (Object[]) PrivateAccessor.getField(mpq, "queue");
			capacity = o.length;
			assertEquals(inputCap, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

		
	}

	/**
	 * Test 5 - On a one element queue, 
	 * 			test the grow method testing to see if the new capacity 
	 * 			is the same as the min capacity when the desired capacity is less than the initial capacity
	 * 
	 */
	@Test
	public void testGrowForNewCapBeingSetToMinCap() {

		mpq = new MyPriorityQueue(64);

		e.setValue(random.nextInt(100));
		
		// add an element to queue
		mpq.add(e);

		o1 = mpq.toArray();

		queueLength = o1.length;

		assertEquals(1, queueLength);
		
		// capacity desired
		int inputCapacity = 64 + random.nextInt(2000);

		try {

			PrivateAccessor.invoke(mpq, "grow", new Class[] { int.class },
					new Object[] { new Integer(inputCapacity) });
			

			o = (Object[]) PrivateAccessor.getField(mpq, "queue");			
			capacity = o.length;
			assertEquals(inputCapacity, capacity);
		} catch (NoSuchFieldException e1) {
		} catch (Throwable e) {
		}

		
	}

	
}